﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Models.NPOI;
using SHZY.DataEncryption;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.Business.Entitys.Dto.QmsBusiInspectionlot;
using SHZY.Business.Entitys;
using SHZY.Business.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SHZY.BaseData.Entitys;
using Org.BouncyCastle.Crypto;
using Yitter.IdGenerator;
using SHZY.Extend.Entitys;
using SHZY.Message.Interfaces;
using Senparc.Weixin;
using SHZY.Business.Entitys.Entity;
using System.Reactive.Joins;
using SHZY.BaseData.Entitys.Entity.Samplingplan;
using Org.BouncyCastle.Asn1.Tsp;
using System.Reactive;
using NPOI.SS.Formula.Functions;
using System.Linq;
using System.Reactive.Linq;
using System.ArrayExtensions;
using Newtonsoft.Json.Linq;
using SHZY.system.Entitys;
using SHZY.BaseData.Interfaces;
using SHZY.BaseData.Entitys.Dto.QmsBaseInspectionrole;
using Spire.Doc.Interface;
using SHZY.BaseData.Entitys.Entity;
using SHZY.Message.Interfaces.Message;
using System.Runtime.CompilerServices;
using static SHZY.Business.QmsBusiInspectionService;
using SHZY.Common.Contracts;
using Microsoft.AspNetCore.Identity;
using SHZY.Business.Entitys.Dto.QmsBusiIpqcinspection;
using SHZY.Business.Entitys.Dto.QmsBusiIpqcinspectionlot;

namespace SHZY.Business;

/// <summary>
/// 业务实现：报检单Form.
/// </summary>
[ApiDescriptionSettings(Tag = "Business", Name = "Inspection", Order = 200)]
[Route("api/Business/[controller]")]
public class QmsBusiInspectionService : IQmsBusiInspectionService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 报检单状态
    /// </summary>
    public class Status
    {
        /// <summary>
        /// 未确认
        /// </summary>
        public const int Unconfirmed = 0;

        /// <summary>
        /// 已提交
        /// </summary>
        public const int Submitted = 1;

        /// <summary>
        /// 已确认
        /// </summary>
        public const int Confirmed = 2;
    }

    /// <summary>
    /// 报检单号
    /// </summary>
    public const string BILL_CODE_BUSIINSPECTION_IQC = "BusiInspection.IQC";
    /// <summary>
    /// 检验批号
    /// </summary>
    public const string BILL_CODE_BUSIINSPECTIONLOT = "BusiInspectionLot";

    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBusiInspectionEntity> _repository;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager userManager;
    private readonly IBillRullService billRullService;
    private readonly IQmsBaseExemptionruleService qmsBaseExemptionruleService;
    private readonly IWeiXinService weiXinService;
    private readonly IMessageService messageService;
    private readonly IDictionaryTypeService dictionaryTypeService;
    private readonly IDictionaryDataService dictionaryDataService;

    /// <summary>
    /// 初始化一个<see cref="QmsBusiInspectionService"/>类型的新实例.
    /// </summary>
    public QmsBusiInspectionService(
         ISqlSugarRepository<QmsBusiInspectionEntity> qmsBusiInspectionlotRepository,
         IDataInterfaceService dataInterfaceService,
         ISqlSugarClient context,
         IUserManager userManager,
         IBillRullService billRullService,
         IQmsBaseExemptionruleService qmsBaseExemptionruleService,
         IWeiXinService weiXinService,
         IMessageService messageService,
         IDictionaryTypeService dictionaryTypeService,
         IDictionaryDataService dictionaryDataService)
    {
        _repository = qmsBusiInspectionlotRepository;
        _dataInterfaceService = dataInterfaceService;
        _db = context.AsTenant();
        this.userManager = userManager;
        this.billRullService = billRullService;
        this.qmsBaseExemptionruleService = qmsBaseExemptionruleService;
        this.weiXinService = weiXinService;
        this.messageService = messageService;
        this.dictionaryTypeService = dictionaryTypeService;
        this.dictionaryDataService = dictionaryDataService;

    }

    /// <summary>
    /// 获取报检单Form.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        //return (await _repository.Context.FirstOrDefaultAsync().Adapt<QmsBusiInspectionlotInfoOutput>();

        var result = _repository.Context.Queryable<QmsBusiInspectionEntity>()
            .LeftJoin<QmsBaseSupplierEntity>((it, b) => it.Supplier == b.Code)
            .LeftJoin<QmsBaseMaterialEntity>((it, b, c) => it.MaterialCode == c.Code)
            .Where(it => it.DeleteMark == null)
            .Select((it, b, c) => new QmsBusiInspectionInfoOutput
            {
                id = it.Id,
                inspectionCode = it.Code,
                materialCode = it.MaterialCode,
                material = c.Name,
                supplierCode = b.Code,
                supplier = b.Name,
                employeeCode = it.EmployeeCode,
                employeeName = it.EmployeeName,
                incomingQty = it.IncomingQty,
                orderNo = it.OrderNo,
                remark = it.Remark,
            }).FirstAsync();

        return result;
    }

    /// <summary>
    /// 获取报检单Form列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBusiInspectionListQueryInput input)
    {
        var data = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
            .LeftJoin<QmsBaseSupplierEntity>((it, b) => it.Supplier == b.Code && b.DeleteMark == null && b.EnabledMark == 1)
            .LeftJoin<QmsBaseMaterialEntity>((it, b, c) => it.MaterialCode == c.Code && c.DeleteMark == null && b.EnabledMark == 1)
            .LeftJoin<DictionaryDataEntity>((it, b, c, d) => it.InspectType == d.EnCode && d.DictionaryTypeId == "458162035063023429")
            .Where(it => it.DeleteMark == null)
            //.Where(it => it.Status == Status.Unconfirmed)
            .WhereIF(input.status != null, it => it.Status == input.status)
            .WhereIF(!string.IsNullOrEmpty(input.inspectionCode), it => it.Code.Contains(input.inspectionCode))
            .WhereIF(!string.IsNullOrEmpty(input.materialCode), it => it.MaterialCode.Equals(input.materialCode))
            .WhereIF(!string.IsNullOrEmpty(input.supplier), it => it.Supplier.Equals(input.supplier))
            .WhereIF(!string.IsNullOrEmpty(input.batchNumber), it => it.BatchNumber.Equals(input.batchNumber))
            .WhereIF(!string.IsNullOrEmpty(input.orderNo), it => it.OrderNo.Contains(input.orderNo))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.MaterialCode.Contains(input.keyword) || it.Supplier.Contains(input.keyword) || it.BatchNumber.Contains(input.keyword) || it.OrderNo.Contains(input.keyword) || it.Remark.Contains(input.keyword))
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.CreatorTime, OrderByType.Desc)
            .Select((it, b, c, d) => new QmsBusiInspectionListOutput
            {
                id = it.Id,
                inspectionCode = it.Code,
                materialCode = it.MaterialCode,
                material = c.Name,
                supplierCode = b.Code,
                supplier = b.Name,
                inspectTypeCode = it.InspectType,
                inspectTypeName = d.FullName,
                employeeCode = it.EmployeeCode,
                employeeName = it.EmployeeName,
                batchNumber = it.BatchNumber,
                incomingQty = it.IncomingQty,
                orderNo = it.OrderNo,
                remark = it.Remark,
                overdue = it.Overdue,
                status = it.Status,
            }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort)
            .ToPagedListAsync(input.currentPage, input.pageSize);

        data.list = data.list.Select(s =>
        {
            //0 未确认 1 已提交   2 已确认
            s.statusDesc = s.status switch
            {
                0 => "未确认",
                1 => "已提交",
                2 => "已确认",
                _ => "未知状态",
            };

            return s;
        });

        return PageResult<QmsBusiInspectionListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 新建报检单Form.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] List<QmsBusiInspectionCrInput> inputs)
    {
        if (!inputs.Any()) return;

        var entitys = inputs.Adapt<List<QmsBusiInspectionEntity>>();
        var index = 1;

        foreach (var inspection in entitys)
        {
            UserEntity inspector;
            // 如果没有指定检验员，就通过跳检规则进行匹配检验员
            if (string.IsNullOrWhiteSpace(inspection.EmployeeCode))
            {
                // 物料信息
                var materia = await _repository.Context
                    .Queryable<QmsBaseMaterialEntity>()
                    .Where(a => a.Code == inspection.MaterialCode)
                    .FirstAsync() ?? throw Oops.Oh($"物料({inspection.Code})信息不存在！");

                // 供应商信息
                var supplier = await _repository.Context
                    .Queryable<QmsBaseSupplierEntity>()
                    .Where(w => w.Code == inspection.Supplier)
                    .FirstAsync() ?? throw Oops.Oh($"供应商({inspection.Supplier})信息不存在！");

                // 跳检规则
                var rules = await _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
                .Where(w => w.DeleteMark == null && w.EnabledMark == 1)
                .Where(w => (w.MatnrCode == materia.Code || w.MatnrCode == null)
                    && (w.MatnrGroupCode == materia.MaterialGroupCode || w.MatnrGroupCode == null)
                    && (w.SupplierNo == supplier.Code || w.SupplierNo == null)
                    && (w.SupplierClassify == supplier.Classify || w.SupplierClassify == null))
                .ToListAsync();

                if (!rules.Any())
                {
                    throw Oops.Oh($"第{index}行报检单未匹配到检验员，请确认!");
                }

                var rule = rules.Select(rule =>
                {
                    var priority = rule.MatnrCode == materia.Code ? 1 : 0;
                    priority += rule.MatnrGroupCode == materia.MaterialGroupCode ? 1 : 0;
                    priority += rule.SupplierNo == supplier.Code ? 1 : 0;
                    priority += rule.SupplierClassify == supplier.Classify ? 1 : 0;

                    return (Priority: priority, Rule: rule);
                }).MaxBy(m => m.Priority).Rule;

                inspector = await _repository.Context.Queryable<UserEntity>()
                    .Where(w => w.EnabledMark == 1 && w.DeleteMark == null)
                    .Where(w => w.Account == rule.EmployeeCode || w.Id == rule.EmployeeCode)
                    .FirstAsync() ?? throw Oops.Oh($"第{index}行报检单匹配到的检验员({rule.EmployeeCode})不可用！");
            }
            else
            {
                // var rlueforUserInfo = await _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
                //.InnerJoin<QmsBaseMaterialEntity>((w, b) => b.Code == fe.MaterialCode)
                //.InnerJoin<QmsBaseSupplierEntity>((w, b, c) => c.Code == fe.Supplier)
                //.InnerJoin<UserEntity>((w, b, c, d) => d.Id == fe.EmployeeCode)
                //.Where(w => w.DeleteMark == null && w.EnabledMark == 1)
                //.Where((w, b, c, d) => w.EmployeeCode == d.Account)
                //.Where((w, b, c) => (w.MatnrCode == b.Code || w.MatnrCode == null)
                //    && (w.MatnrGroupCode == b.MaterialGroupCode || w.MatnrGroupCode == null)
                //    && (w.SupplierNo == c.Code || w.SupplierNo == null)
                //    && (w.SupplierClassify == c.Classify || w.SupplierClassify == null))
                //.Select((w, b, c, d) => d).FirstAsync() ?? throw Oops.Oh($"第{index}行报检单未匹配到检验员，请确认!");

                inspector = await _repository.Context.Queryable<UserEntity>()
                    .Where(w => w.Id == inspection.EmployeeCode).FirstAsync() ?? throw Oops.Oh($"第{index}行报检单指定的检验员({inspection.EmployeeCode})不可用！");
            }

            inspection.EmployeeCode = inspector.Account;
            inspection.EmployeeName = inspector.RealName;
            inspection.Status = 0;
            inspection.Type = "IQC";
            inspection.Code = await billRullService.GetBillNumber(BILL_CODE_BUSIINSPECTION_IQC);
            index++;
        }

        try
        {
            // 开启事务
            _db.BeginTran();

            var isOk = await _repository.Context.Insertable(entitys)
                //.InsertColumns(a => new { a.IncomingQty, a.BatchNumber, a.Code,a.EnabledMark,a. })
                .CallEntityMethod(a => a.Creator())
                .ExecuteCommandAsync();
            if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);

            // 关闭事务
            _db.CommitTran();
        }
        catch (Exception)
        {
            // 回滚事务
            _db.RollbackTran();

            throw Oops.Oh(ErrorCode.COM1002);
        }
    }

    /// <summary>
    /// 获取报检单Form无分页列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    private async Task<dynamic> GetNoPagingList([FromQuery] QmsBusiInspectionListQueryInput input)
    {
        var data = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
            .LeftJoin<QmsBaseSupplierEntity>((it, b) => it.Supplier == b.Code && b.DeleteMark == null && b.EnabledMark == 1)
            .LeftJoin<QmsBaseMaterialEntity>((it, b, c) => it.MaterialCode == c.Code && c.DeleteMark == null && b.EnabledMark == 1)
            .LeftJoin<DictionaryDataEntity>((it, b, c, d) => it.InspectType == d.EnCode && d.DictionaryTypeId == "458162035063023429")
            .Where(it => it.DeleteMark == null)
            //.Where(it => it.Status == Status.Unconfirmed)
            .WhereIF(input.status != null, it => it.Status == input.status)
            .WhereIF(!string.IsNullOrEmpty(input.inspectionCode), it => it.Code.Contains(input.inspectionCode))
            .WhereIF(!string.IsNullOrEmpty(input.materialCode), it => it.MaterialCode.Equals(input.materialCode))
            .WhereIF(!string.IsNullOrEmpty(input.supplier), it => it.Supplier.Equals(input.supplier))
            .WhereIF(!string.IsNullOrEmpty(input.batchNumber), it => it.BatchNumber.Equals(input.batchNumber))
            .WhereIF(!string.IsNullOrEmpty(input.orderNo), it => it.OrderNo.Contains(input.orderNo))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.MaterialCode.Contains(input.keyword) || it.Supplier.Contains(input.keyword) || it.BatchNumber.Contains(input.keyword) || it.OrderNo.Contains(input.keyword) || it.Remark.Contains(input.keyword))
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.CreatorTime, OrderByType.Desc)
            .Select((it, b, c, d) => new QmsBusiInspectionListOutput
            {
                id = it.Id,
                inspectionCode = it.Code,
                materialCode = it.MaterialCode,
                material = c.Name,
                supplierCode = b.Code,
                supplier = b.Name,
                inspectTypeCode = it.InspectType,
                inspectTypeName = d.FullName,
                employeeCode = it.EmployeeCode,
                employeeName = it.EmployeeName,
                batchNumber = it.BatchNumber,
                incomingQty = it.IncomingQty,
                orderNo = it.OrderNo,
                remark = it.Remark,
                overdue = it.Overdue,
                status = it.Status
            }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToListAsync();

        data = data.Select(s =>
        {
            s.statusDesc = s.status switch
            {
                0 => "未确认",
                1 => "已提交",
                2 => "已确认",
                _ => "未知状态",
            };

            return s;
        }).ToList();

        return data;
    }

    /// <summary>
    /// 导出报检单Form.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Actions/Export")]
    public async Task<dynamic> Export([FromQuery] QmsBusiInspectionListQueryInput input)
    {
        var exportData = new List<QmsBusiInspectionListOutput>();
        if (input.dataType == 0)
            exportData = Clay.Object(await GetList(input)).Solidify<PageResult<QmsBusiInspectionListOutput>>().list;
        else
            exportData = await GetNoPagingList(input);
        //List<ParamsModel> paramList = "[{\"value\":\"物料\",\"field\":\"materialCode\"},{\"value\":\"供应商\",\"field\":\"supplier\"},{\"value\":\"来料数量\",\"field\":\"incomingQty\"},{\"value\":\"批次号\",\"field\":\"batchNumber\"},{\"value\":\"采购订单号\",\"field\":\"orderNo\"},{\"value\":\"备注\",\"field\":\"remark\"},]".ToList<ParamsModel>();
        List<ParamsModel> paramList = new()
        {
            new ParamsModel { field = "inspectionCode", value = "报检单号" },
            new ParamsModel { field = "statusDesc", value = "状态" },
            new ParamsModel { field = "materialCode", value = "物料编号" },
            new ParamsModel { field = "material", value = "物料" },
            new ParamsModel { field = "supplierCode", value = "供应商编号" },
            new ParamsModel { field = "supplier", value = "供应商" },
            new ParamsModel { field = "inspectTypeCode", value = "检验类型编号" },
            new ParamsModel { field = "inspectTypeName", value = "检验类型" },
            new ParamsModel { field = "employeeCode", value = "检验员工号" },
            new ParamsModel { field = "employeeName", value = "检验员" },
            new ParamsModel { field = "batchNumber", value = "批次号" },
            new ParamsModel { field = "incomingQty", value = "来料数量" },
            new ParamsModel { field = "orderNo", value = "采购订单号" },
            new ParamsModel { field = "remark", value = "备注" },
            new ParamsModel { field = "overdue", value = "是否逾期" },
        };
        ExcelConfig excelconfig = new ExcelConfig();
        excelconfig.FileName = "报检单Form.xls";
        excelconfig.HeadFont = "微软雅黑";
        excelconfig.HeadPoint = 10;
        excelconfig.IsAllSizeColumn = true;
        excelconfig.ColumnModel = new List<ExcelColumnModel>();
        foreach (var item in input.selectKey.Split(',').ToList())
        {
            var isExist = paramList.Find(p => p.field == item);
            if (isExist != null)
                excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
        }

        var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
        ExcelExportHelper<QmsBusiInspectionListOutput>.Export(exportData, excelconfig, addPath);
        var fileName = userManager.UserId + "|" + addPath + "|xls";
        return new
        {
            name = excelconfig.FileName,
            url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
        };
    }

    /// <summary>
    /// 批量删除报检单Form.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("batchRemove")]
    public async Task BatchRemove([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<QmsBusiInspectionEntity>().In(it => it.Id, ids).ToListAsync();
        if (entitys.Count > 0)
        {
            try
            {
                // 开启事务
                _db.BeginTran();

                // 批量删除报检单Form
                var isOk = await _repository.Context.Updateable<QmsBusiInspectionEntity>()
               .SetColumns(it => new QmsBusiInspectionEntity()
               {
                   DeleteTime = DateTime.Now,
                   DeleteMark = 1,
                   DeleteUserId = userManager.UserId
               }).Where(x => ids.Contains(x.Id))
               .ExecuteCommandHasChangeAsync();

                if (!isOk) throw Oops.Oh(ErrorCode.COM1002);

                // 关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                // 回滚事务
                _db.RollbackTran();

                throw Oops.Oh(ErrorCode.COM1002);
            }
        }
    }

    /// <summary>
    /// 更新报检单Form.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBusiInspectionUpInput input)
    {
        var entity = input.Adapt<QmsBusiInspectionEntity>();
        var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new
        {
            it.MaterialCode,
            it.Supplier,
            it.IncomingQty,
            it.BatchNumber,
            it.OrderNo,
            it.Remark,
            it.LastModifyTime,
            it.LastModifyUserId,
            it.EnabledMark,
        }).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除报检单Form.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        //var isOk = await _repository.Context
        //    .Deleteable<QmsBusiInspectionEntity>()
        //    .Where(it => it.Id.Equals(id))
        //    .ExecuteCommandAsync();
        //if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);

        var isOk = await _repository.Context.Updateable<QmsBusiInspectionEntity>()
           .SetColumns(it => new QmsBusiInspectionEntity()
           {
               DeleteTime = DateTime.Now,
               DeleteMark = 1,
               DeleteUserId = userManager.UserId
           }).Where(x => x.Id == id)
           .ExecuteCommandHasChangeAsync();

        if (!isOk) throw Oops.Oh(ErrorCode.COM1002);
    }

    /// <summary>
    /// 确认报检单
    /// </summary>
    /// <param name="code"></param>
    [HttpPost(nameof(Confirm) + "/{code}")]
    public async Task<string> Confirm(string code)
    {
        try
        {
            QmsBusiInspectionEntity inspection = await GetInspectionOfUnconfirmedByCodeOrIdAsync(code);
            await ConfirmInspectionAsync(inspection);

            return string.Empty;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }

    /// <summary>
    /// 批量确认报检单
    /// </summary>
    /// <param name="codes"></param>
    /// <returns></returns>
    [HttpPost(nameof(BatchConfirm))]
    public async Task<string> BatchConfirm([FromBody] List<string> codes)
    {
        Task[] taskList = codes.Select(async code =>
        {
            QmsBusiInspectionEntity inspection = await GetInspectionOfUnconfirmedByCodeOrIdAsync(code);
            await ConfirmInspectionAsync(inspection);
        }).ToArray();

        await Task.WhenAll(taskList);
        var errorArray = taskList.Where(w => w.IsFaulted).Select(s => s.Exception?.Message).ToArray();
        string messsage = string.Join(Environment.NewLine, errorArray);

        return messsage;
    }


    /// <inheritdoc/>
    public async Task AutoGenerateInspection()
    {
        try
        {
            var inspectionList = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
                .Where(it => it.DeleteMark == null)
                .Where(it => it.Status == Status.Unconfirmed)
                .ToListAsync();

            // 执行合批逻辑
            var combineBatchResult = await GenerateCombineBatchList(inspectionList);

            // 执行确认逻辑
            foreach (var combineBatchInspectionList in combineBatchResult)
            {
                try
                {
                    // 生成虚拟的合批报检单据
                    var tempInspection = combineBatchInspectionList.First();
                    var virtualinspection = new QmsBusiInspectionEntity
                    {
                        Type = tempInspection.Type,
                        MaterialCode = tempInspection.MaterialCode,
                        Supplier = tempInspection.Supplier,
                        BatchNumber = tempInspection.BatchNumber,
                        InspectType = tempInspection.InspectType,
                        OrderNo = tempInspection.OrderNo,
                        Remark = tempInspection.Remark,
                        Status = tempInspection.Status,
                        IncomingQty = combineBatchInspectionList.Sum(s => s.IncomingQty)
                    };

                    await ConfirmInspectionWithCombineBatchAsync(false, virtualinspection, combineBatchInspectionList.ToArray());
                }
                catch (Exception ex)
                {
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// 生成合批列表:根据报检单编号或ID生成合批列表
    /// </summary>
    /// <param name="inspectionList">报检单编号或ID</param>
    /// <returns></returns>
    public async Task<IEnumerable<IEnumerable<QmsBusiInspectionEntity>>> GenerateCombineBatchList(List<QmsBusiInspectionEntity> inspectionList)
    {
        //if (idOrCodes.Count <= 1) throw Oops.Bah("当个报检单不需要进行合批操作！");

        //// 报检单据
        //var inspectionList = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
        //    .Where(a => a.DeleteMark == null)
        //    .Where(a => a.Status == Status.Unconfirmed)
        //    .Where(a => idOrCodes.Contains(a.Code) || idOrCodes.Contains(a.Id))
        //    .ToListAsync();

        if (inspectionList.Count <= 1) throw Oops.Bah("查询到的报检单据数量，不需要进行合批操作！");

        var combineRules = await _repository.Context.Queryable<QmsBaseInspcombinesettingEntity>()
                .Where(w => w.EnabledMark == 1)
                .Where(w => w.DeleteMark == null)
                .Where(w => w.Type == "IQC")
                .Where(w => w.MergeConditions != null)
                .ToListAsync();

        var combineRule = combineRules.MinBy(m => m.MergeConditions.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Length)
                ?? throw Oops.Bah("未找到当前(IQC)业务类型的合批规则！");

        List<QmsBusiInspectionEntity[]> result = inspectionList.GroupBy(a =>
        {
            // ["BatchNumber","Supplier","Material"]
            var str = combineRule.MergeConditions.Contains("Material", StringComparison.OrdinalIgnoreCase) ? a.MaterialCode : string.Empty;
            str += combineRule.MergeConditions.Contains("Supplier", StringComparison.OrdinalIgnoreCase) ? a.Supplier : string.Empty;
            str += combineRule.MergeConditions.Contains("BatchNumber", StringComparison.OrdinalIgnoreCase) ? a.BatchNumber : string.Empty;
            str += combineRule.MergeConditions.Contains("PurchaseCxategory", StringComparison.OrdinalIgnoreCase) ? a.InspectType : string.Empty;
            str += string.IsNullOrWhiteSpace(a.EmployeeCode) ? string.Empty : a.EmployeeCode;

            return str;
        }).Select(s => s.ToArray()).ToList();

        return result;
    }

    /// <summary>
    /// 报检单合批
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [HttpPost(nameof(CombineBatch))]
    public async Task<string> CombineBatch([FromBody] List<string> ids)
    {
        try
        {
            // 报检单据
            var inspectionList = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
                .Where(a => a.DeleteMark == null)
                .Where(a => a.Status == Status.Unconfirmed)
                .Where(a => ids.Contains(a.Code) || ids.Contains(a.Id))
                .ToListAsync();

            if (inspectionList.Count <= 1) throw Oops.Bah("当个报检单不需要进行合批操作！");

            if (inspectionList.DistinctBy(a => $"{a.MaterialCode},{a.Supplier},{a.BatchNumber},{a.EmployeeCode}").Count() > 1)
                throw Oops.Bah("只有【供应商，批次号，物料号，检验员】相同的报检单才能进行合批操作！");

            var combineRules = await _repository.Context.Queryable<QmsBaseInspcombinesettingEntity>()
                .Where(w => w.EnabledMark == 1)
                .Where(w => w.DeleteMark == null)
                .Where(w => w.Type == "IQC")
                .Where(w => w.MergeConditions != null)
                .ToListAsync();

            var combineRule = combineRules.MinBy(m => m.MergeConditions.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Length)
                ?? throw Oops.Bah("未找到当前(IQC)业务类型的合批规则！");

            // 执行合批逻辑
            // 匹配合批规则：大于1表示存在不同【供应商，批次号，物料号，检验类型，检验员】的报检单
            if (inspectionList.DistinctBy(a =>
            {
                // ["BatchNumber","Supplier","Material"]
                var str = combineRule.MergeConditions.Contains("Material", StringComparison.OrdinalIgnoreCase) ? a.MaterialCode : string.Empty;
                str += combineRule.MergeConditions.Contains("Supplier", StringComparison.OrdinalIgnoreCase) ? a.Supplier : string.Empty;
                str += combineRule.MergeConditions.Contains("BatchNumber", StringComparison.OrdinalIgnoreCase) ? a.BatchNumber : string.Empty;
                str += combineRule.MergeConditions.Contains("PurchaseCategory", StringComparison.OrdinalIgnoreCase) ? a.InspectType : string.Empty;
                str += string.IsNullOrWhiteSpace(a.EmployeeCode) ? string.Empty : a.EmployeeCode;

                return str;
            }).Count() > 1)
                throw Oops.Bah($"合批规则({combineRule.Id}):只有相同【{combineRule.MergeConditionsName}】的报检单才能进行合批操作！");

            // 执行确认逻辑
            // 生成虚拟的合批报检单据
            var tempInspection = inspectionList.First();
            var inspection = new QmsBusiInspectionEntity
            {
                Type = tempInspection.Type,
                MaterialCode = tempInspection.MaterialCode,
                Supplier = tempInspection.Supplier,
                BatchNumber = tempInspection.BatchNumber,
                InspectType = tempInspection.InspectType,
                OrderNo = tempInspection.OrderNo,
                Remark = tempInspection.Remark,
                Status = tempInspection.Status,
                IncomingQty = inspectionList.Sum(s => s.IncomingQty)
            };

            await ConfirmInspectionWithCombineBatchAsync(true, inspection, inspectionList.ToArray());

            return string.Empty;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }

    /// <summary>
    /// 获取未确认报检单据:根据报检单编号或报检单ID获取报检单据
    /// </summary>
    /// <param name="codeOrId">报检单编号或报检单ID</param>
    /// <returns>报检单单据</returns>
    private async Task<QmsBusiInspectionEntity> GetInspectionOfUnconfirmedByCodeOrIdAsync(string codeOrId)
    {
        // 报检单据
        var inspection = await _repository.Context.Queryable<QmsBusiInspectionEntity>()
            .Where(a => a.DeleteMark == null)
            .Where(a => a.Status == Status.Unconfirmed)
            .Where(a => a.Code == codeOrId || a.Id == codeOrId)
            .FirstAsync() ?? throw Oops.Oh($"报检单({codeOrId})单据不存在！");

        return inspection;
    }

    /// <summary>
    /// 报检单确认：根据报检单单据信息生成检验批和检验批项目
    /// </summary>
    /// <param name="inspection">报检单单据</param>
    /// <returns></returns>
    private async Task ConfirmInspectionAsync(QmsBusiInspectionEntity inspection)
    {
        await ConfirmInspectionWithCombineBatchAsync(true, inspection, inspection);
    }

    /// <summary>
    /// 报检单合批确认：根据报检单单据信息生成检验批和检验批项目
    /// </summary>
    /// <param name="isLogin">是否为用户操作</param>
    /// <param name="inspection">用于生成检验批和检验批项目的报检单数据</param>
    /// <param name="wantInspectionList">需要更新数据库状态的检验单据</param>
    /// <returns></returns>
    private async Task ConfirmInspectionWithCombineBatchAsync(bool isLogin, QmsBusiInspectionEntity inspection, params QmsBusiInspectionEntity[] wantInspectionList)
    {
        // 物料信息
        var materia = await _repository.Context
            .Queryable<QmsBaseMaterialEntity>()
            .Where(a => a.Code == inspection.MaterialCode)
            .FirstAsync() ?? throw Oops.Oh($"物料({inspection.MaterialCode})信息不存在！");


        // 供应商信息
        var supplier = await _repository.Context
            .Queryable<QmsBaseSupplierEntity>()
            .Where(w => w.Code == inspection.Supplier)
            .FirstAsync() ?? throw Oops.Oh($"供应商({inspection.Supplier})信息不存在！");

        // 检验员
        var inspector = new UserEntity();

        // 任务分配规则:如果已经分配了检验员，就不使用任务分配规则进行分配了
        if (!string.IsNullOrWhiteSpace(inspection.EmployeeCode))
        {
            inspector = await _repository.Context.Queryable<UserEntity>()
                     .Where(w => w.EnabledMark == 1 && w.DeleteMark == null)
                     .Where(w => w.Account == inspection.EmployeeCode || w.Id == inspection.EmployeeCode)
                     .FirstAsync() ?? throw Oops.Oh($"检验员{inspection.EmployeeCode}不可用！");
        }
        else
        {
            var rules = await _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
               .Where(w => w.DeleteMark == null && w.EnabledMark == 1)
               // .Where(w => w.MatnrCode == materia.Code || w.MatnrGroupCode == materia.MaterialGroupCode || w.SupplierNo == supplier.Code || w.SupplierClassify == supplier.Classify)
               .Where(w => (w.MatnrCode == materia.Code || w.MatnrCode == null)
                   && (w.MatnrGroupCode == materia.MaterialGroupCode || w.MatnrGroupCode == null)
                   && (w.SupplierNo == supplier.Code || w.SupplierNo == null)
                   && (w.SupplierClassify == supplier.Classify || w.SupplierClassify == null))
               .ToListAsync();

            if (!rules.Any())
            {
                throw Oops.Oh($"物料({inspection.MaterialCode})没有匹配到检验任务分配规则！");
            }

            var rule = rules.Select(rule =>
            {
                var priority = rule.MatnrCode == materia.Code ? 1 : 0;
                priority += rule.MatnrGroupCode == materia.MaterialGroupCode ? 1 : 0;
                priority += rule.SupplierNo == supplier.Code ? 1 : 0;
                priority += rule.SupplierClassify == supplier.Classify ? 1 : 0;

                return (Priority: priority, Rule: rule);
            }).MaxBy(m => m.Priority).Rule;

            inspector = await _repository.Context.Queryable<UserEntity>()
                .Where(w => w.EnabledMark == 1 && w.DeleteMark == null)
                .Where(w => w.Account == rule.EmployeeCode || w.Id == rule.EmployeeCode)
                .FirstAsync() ?? throw Oops.Oh($"检验员{rule.EmployeeCode}不可用！");
        }

        // 抽样方案类型
        var sampleTypeKey = await dictionaryTypeService.GetInfo("sampleType") ?? throw Oops.Oh("读取抽样方案字典信息失败！");
        var sampleTypeList = await dictionaryDataService.GetList(sampleTypeKey.Id);

        // 自定义参数字典
        var customParameterTypeKey = await dictionaryTypeService.GetInfo("customParameter") ?? throw Oops.Oh("读取自定义参数字典信息失败！");

        // 执行跳检规则
        var executeRuleResult = await ExecuteRule(materia.Code, inspection.InspectType, supplier.Code, isLogin);
        // 是否免检
        var isExempt = executeRuleResult != null && executeRuleResult["isExempt"].ToString() == "1";

        // 检卡
        var checkCard = await _repository.Context
            .Queryable<QmsBaseCheckcardEntity>()
            .InnerJoin<QmsBaseCheckcardmaterialEntity>((w, b) => w.Id == b.ParentId)
            .Where((w, b) => w.EnabledMark == 1 && b.EnabledMark == 1)
            .Where((w, b) => w.DeleteMark == null && b.DeleteMark == null)
            .Where((w, b) => b.MaterialCode == materia.Code)
            .Where(w => w.Business == "IQC" || w.Business.Contains(",IQC") || w.Business.Contains("IQC,"))
            .OrderByDescending(w => w.LastModifyTime).OrderByDescending(w => w.CreatorTime)
            .FirstAsync() ?? throw Oops.Oh($"物料({materia.Code})没有对应的检卡信息！");

        // 抽样方案及检验项目
        var checkCardSampleList = await _repository.Context.Queryable<QmsBaseCheckcardsampleEntity>()
            .LeftJoin<QmsBaseCheckcarddetailEntity>((a, b) => a.Id == b.SampleId)
            .Where((a, b) => a.EnabledMark == 1 && b.EnabledMark == 1)
            .Where((a, b) => a.DeleteMark == null && b.DeleteMark == null)
            .Where((a, b) => a.CheckGuid == checkCard.Id)
            // 如果开启了限定逻辑，则限定业务类型与当前报检单类型一致
            .Where((a, b) => b.QualifyingLogic == null || b.QualifyingLogic == "N"
            || (b.Supplier == inspection.Supplier && (b.BusinessType == inspection.InspectType || b.BusinessType.Contains($"{inspection.InspectType},") || b.BusinessType.Contains($",{inspection.InspectType}")) && b.Customer == b.Customer))
            .Select((a, b) => new { Sample = a, Detail = b, CustomParameters = b.CustomParameters.ToString() })
            .ToListAsync();

        // 抽样方案列表
        var sampleCheckItemList = checkCardSampleList.GroupBy(g => g.Sample.Id, (k, v) => new
        {
            SamplePlan = v.First().Sample,
            CheckCardDetailList = v.Select(s =>
            {
                s.Detail.CustomParameters = s.CustomParameters!;
                return s.Detail;
            })
        }).ToList();

        // 生成检验批，根据检验项目
        var inspectionLotItemEntityList = sampleCheckItemList.SelectMany(fe =>
        {
            var samplePlan = fe.SamplePlan;
            var sampleType = sampleTypeList.FirstOrDefault(s => s.EnCode == samplePlan.SamplingType)
                ?? throw Oops.Oh($"抽样方案({samplePlan.SamplingType})不可用！");

            return fe.CheckCardDetailList.Select(item =>
            {
                decimal receivedQty = 0;
                decimal rejectionQty = 1;
                var samplingQty = samplePlan.SamplingType switch
                {
                    "1" => GBAQL(samplePlan, inspection.IncomingQty ?? 0, out receivedQty, out rejectionQty), // 国标AQL
                    "2" => receivedQty = samplePlan.FixedSamplingQty ?? 0, // 固定抽样
                    "3" => FixRate(samplePlan, inspection.IncomingQty ?? 0, out receivedQty, out rejectionQty), // 固定比例
                    "4" => CoustomerAQL(samplePlan.Aql, inspection.IncomingQty ?? 0, out receivedQty, out rejectionQty), // 自定义AQL
                    "5" => 0, // 执行时自行设置
                    _ => throw Oops.Oh($"无效的类型({samplePlan.SamplingType})!")
                };

                // 检验项目
                var inspectionItemEntity = _repository.Context.Queryable<QmsBaseInnspectionitemsEntity>()
                .Where(w => w.EnabledMark == 1)
                .Where(w => w.DeleteMark == null)
                .Where(w => w.Id == item.InnspectionName || w.InnspectionName == item.InnspectionName)
                .First() ?? throw Oops.Oh($"无效的检验项目({item.InnspectionName})!");

                // 检验条目
                var inspectionEntityEntity = _repository.Context.Queryable<QmsBaseInnspectionentryEntity>()
                .Where(w => w.EnabledMark == 1)
                .Where(w => w.DeleteMark == null)
                .Where(w => w.Id == item.InnspectionEntry || w.InnspectionName == item.InnspectionEntry)
                .First() ?? throw Oops.Oh($"无效的检验条目({item.InnspectionEntry})!");

                // 检验方法
                var inspectionMethodEntity = _repository.Context.Queryable<QmsBaseInnspectionmethodEntity>()
                .Where(w => w.EnabledMark == 1)
                .Where(w => w.DeleteMark == null)
                .Where(w => w.Id == item.InnspectionMethod || w.Name == item.InnspectionMethod)
                .First() ?? throw Oops.Oh($"无效的检验方法({item.InnspectionMethod})!");

                // [{"key":"SN_No","label":"SN号","value":"1236666"},{"key":"Lot_No","label":"批次号","value":"456"}]
                string parameterResult = CustomerParamToJson(item.CustomParameters, customParameterTypeKey.Id);

                return new QmsBusiInspectionitemEntity
                {
                    Type = item.Type,
                    SampleId = item.SampleId,
                    SamplingType = sampleType.EnCode,
                    SamplingTypeDes = sampleType.FullName,
                    SamplingQty = (int)samplingQty,
                    InnspectionCode = inspectionItemEntity.Id,
                    InnspectionName = inspectionItemEntity.InnspectionName,
                    InnspectionEntry = inspectionEntityEntity.Id,
                    InnspectionEntryName = inspectionEntityEntity.InnspectionName,
                    InnspectionMethod = inspectionMethodEntity.Id,
                    InnspectionMethodName = inspectionMethodEntity.Name,
                    QuantitativeStandards = item.QuantitativeStandards,
                    StandardValue = item.StandardValue,
                    UpperDeviation = item.UpperDeviation,
                    LowerDeviation = item.LowerDeviation,
                    MaximumValue = item.MaximumValue,
                    MinimumValue = item.MinimumValue,
                    Unit = item.Unit,
                    Accuracy = item.Accuracy,
                    FileInfo = item.FileInfo,
                    ReceivedQty = (int)receivedQty,
                    RejectionQty = (int)rejectionQty,
                    Remarks = item.Remarks,
                    ReferTo = item.ReferTo,
                    Destructiveness = item.Destructiveness,
                    DestructivenessQty = 0,
                    Parameter = parameterResult,
                    Status = isExempt ? "OK" : string.Empty,
                    Exempt = isExempt ? "Y" : "N",
                    EnabledMark = 1,
                    CreatorUserId = isLogin ? userManager.UserId : "System",
                    CreatorTime = DateTime.Now,
                    Id = YitIdHelper.NextId().ToString()
                };
            });

        }).ToList();

        if (!inspectionLotItemEntityList.Any())
        {
            throw Oops.Bah($"没有找到物料对应的检验项目：{materia.Code}  {materia.Name}");
        }

        // 转换创建检验批对象自定义参数为JSON格式
        string parameterResult = CustomerParamToJson(checkCard.CustomParameters, customParameterTypeKey.Id);

        // 检验批检验批号.
        string billNo = await billRullService.GetBillNumber(BILL_CODE_BUSIINSPECTIONLOT);

        // 赋值检验批号
        inspectionLotItemEntityList.ForEach(item => item.Code = billNo);

        // 更新报检单信息
        wantInspectionList.ToList().ForEach(inspection =>
        {
            // 更新报检单状态信息
            inspection.InspectionlogCode = billNo;
            inspection.Date = DateTime.Now;
            inspection.Status = Status.Confirmed;
            inspection.EmployeeCode = inspector.Account;
            inspection.EmployeeName = inspector.RealName;
            inspection.LastModifyTime = DateTime.Now;
            inspection.LastModifyUserId = isLogin ? userManager.UserId : "System";
        });

        // 创建检验批对象
        var inspectionLotEntity = new QmsBusiInspectionlotEntity
        {
            Code = billNo,
            Type = inspection.Type,
            MaterialCode = inspection.MaterialCode,
            Supplier = inspection.Supplier,
            IncomingQty = inspection.IncomingQty,
            BatchNumber = inspection.BatchNumber,
            EmployeeCode = inspection.EmployeeCode,
            EmployeeName = inspection.EmployeeName,
            OrderNo = inspection.OrderNo,
            InspectType = inspection.InspectType,
            Remark = inspection.Remark,
            Parameter = parameterResult,
            DestructivenessQty = 0,
            Status = isExempt ? 3 : 0,
            JudgeStatus = isExempt ? "OK" : string.Empty,
            Decision = isExempt ? "101" : string.Empty,
            DecisionName = isExempt ? "合格，接收" : string.Empty,
            EnabledMark = 1,
            CreatorUserId = isLogin ? userManager.UserId : "System",
            CreatorTime = DateTime.Now,
            Exempt = isExempt ? "Y" : "N",
            MaterialFile = materia.FileInfo,
            CheckCardFile = checkCard.FileInfo,
            Id = YitIdHelper.NextId().ToString()
        };

        // 执行数据保存存在
        try
        {
            _repository.Context.BeginTran();

            await _repository.Context.Updateable(wantInspectionList).WhereColumns(u => u.Id).UpdateColumns(u => new
            {
                u.InspectionlogCode,
                u.Date,
                u.Status,
                u.EmployeeCode,
                u.EmployeeName,
                u.LastModifyTime,
                u.LastModifyUserId
            }).ExecuteCommandHasChangeAsync();

            inspectionLotEntity = await _repository.Context.Insertable(inspectionLotEntity).InsertColumns(i => new
            {
                i.Id,
                i.Code,
                i.Type,
                i.MaterialCode,
                i.Supplier,
                i.IncomingQty,
                i.BatchNumber,
                i.EmployeeCode,
                i.EmployeeName,
                i.OrderNo,
                i.InspectType,
                i.Remark,
                i.Parameter,
                i.DestructivenessQty,
                i.Status,
                i.JudgeStatus,
                i.Decision,
                i.DecisionName,
                i.CreatorTime,
                i.CreatorUserId,
                i.EnabledMark,
                i.Exempt,
                i.MaterialFile,
                i.CheckCardFile
            }).ExecuteReturnEntityAsync();

            await _repository.Context.Insertable(inspectionLotItemEntityList).InsertColumns(i => new
            {
                i.Id,
                i.Code,
                i.Type,
                i.SampleId,
                i.SamplingType,
                i.SamplingTypeDes,
                i.SamplingQty,
                i.InnspectionCode,
                i.InnspectionName,
                i.InnspectionEntry,
                i.InnspectionEntryName,
                i.InnspectionMethod,
                i.InnspectionMethodName,
                i.QuantitativeStandards,
                i.StandardValue,
                i.UpperDeviation,
                i.LowerDeviation,
                i.MaximumValue,
                i.MinimumValue,
                i.Unit,
                i.Accuracy,
                i.FileInfo,
                i.ReceivedQty,
                i.RejectionQty,
                i.Remarks,
                i.ReferTo,
                i.Destructiveness,
                i.DestructivenessQty,
                i.Exempt,
                i.Parameter,
                //i.AutoFlag,
                i.Status,
                i.CreatorTime,
                i.CreatorUserId,
                i.EnabledMark
            }).ExecuteCommandAsync();

            // 如果是免检，合格检验数量计数加1
            if (isExempt)
            {
                string recordId = executeRuleResult["id"].ToString();
                var userCode = isLogin ? userManager.UserId : "system";
                var isOk = await _repository.Context.Updateable<QmsBusiExemptionrulerecordEntity>()
                    .SetColumns(it => it.QualifiedInspNumber == it.QualifiedInspNumber + 1)
                    .SetColumns(it => it.LastModifyTime == DateTime.Now)
                    .SetColumns(it => it.LastModifyUserId == userCode)
                    //.SetColumns(it => new QmsBusiExemptionrulerecordEntity()
                    //{
                    //    QualifiedInspNumber = it.QualifiedInspNumber + 1,
                    //    LastModifyTime = DateTime.Now,
                    //    LastModifyUserId = isLogin ? userManager.UserId : "system"
                    //})
                    .Where(x => x.Id == recordId).ExecuteCommandHasChangeAsync();
                if (!isOk)
                    throw Oops.Oh(ErrorCode.COM1001);

                // 记录明细
                var exemptionrulerecorddetailEntity = new QmsBusiExemptionrulerecorddetailEntity();
                exemptionrulerecorddetailEntity.Id = YitIdHelper.NextId().ToString();
                exemptionrulerecorddetailEntity.ParentId = recordId;
                exemptionrulerecorddetailEntity.InspectionlotId = inspectionLotEntity.Id;
                exemptionrulerecorddetailEntity.Status = "OK";
                exemptionrulerecorddetailEntity.EnabledMark = 1;
                exemptionrulerecorddetailEntity.CreatorTime = DateTime.Now;
                exemptionrulerecorddetailEntity.CreatorUserId = isLogin ? userManager.UserId : "system";
                var isOk1 = await _repository.Context.Insertable(exemptionrulerecorddetailEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                if (isOk1 < 1)
                    throw Oops.Oh("插入跳检规则记录明细数据失败");
            }


            _repository.Context.CommitTran();
        }
        catch (Exception ex)
        {
            _repository.Context.RollbackTran();

            throw ex;
        }

        SendMessageEvent(inspectionLotEntity.Code, inspector, isLogin);
        // SendWeiXinMessage(inspectionLotEntity.Id, billNo, $"IQC {materia.Name}", inspector.RealName);
    }


    /// <summary>
    /// 执行跳检规则
    /// </summary>
    /// <param name="materialCode">物料编码</param>
    /// <param name="orderType">采购订单类型</param>
    /// <param name="supplierCode">供应商编码</param>
    /// <returns></returns>
    public async Task<JObject> ExecuteRule(string materialCode, string orderType, string supplierCode, bool isLogin)
    {
        string recordId = "";
        var data = new QmsBaseInspectionroleEntity();
        // 查询当前是否有执行跳检规则
        // 有则返回当前阶段信息
        // 没有则查询是否有分配的跳检规则，获取初始阶段信息
        var recordInfo = await _repository.Context.Queryable<QmsBusiExemptionrulerecordEntity>().Where(x => x.MatnrCode == materialCode && x.OrderType == orderType && x.SupplierNo == supplierCode && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
        if (recordInfo != null)
        {
            data = await _repository.Context.Queryable<QmsBaseInspectionrolemainEntity, QmsBaseInspectionroleEntity>((a, b) => a.Id == b.MainId).Where((a, b) => a.Code == recordInfo.RuleCode && b.Stage == recordInfo.Stage && a.DeleteMark == null && a.EnabledMark == 1 && b.DeleteMark == null && b.EnabledMark == 1).Select((a, b) => b).FirstAsync();
            if (data == null)
                throw Oops.Oh("根据跳检规则记录未查询到跳检配置，请确认");
            // 校验规则
            data = CheckRule(recordInfo, data, isLogin).Result;
            recordId = recordInfo.Id;
        }
        else
        {
            var currentDate = DateTime.Now;
            var ruleInfo = await _repository.Context.Queryable<QmsBaseExemptionruleEntity>().Where(x => x.Matnr == materialCode && x.OrderType == orderType && x.SupplierNo == supplierCode && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            if (ruleInfo != null)
            {
                data = await _repository.Context.Queryable<QmsBaseInspectionrolemainEntity, QmsBaseInspectionroleEntity>((a, b) => a.Id == b.MainId).Where((a, b) => a.Code == ruleInfo.RuleCode && a.StartDate <= currentDate && a.EndDate >= currentDate && b.IsDefault == 1 && a.DeleteMark == null && a.EnabledMark == 1 && b.DeleteMark == null && b.EnabledMark == 1).Select((a, b) => b).FirstAsync();
                if (data == null)
                    throw Oops.Oh("根据分配的跳检规则未查询到初始阶段，请确认");
                QmsBusiExemptionrulerecordEntity _QmsBusiExemptionrulerecordEntity = new QmsBusiExemptionrulerecordEntity();
                _QmsBusiExemptionrulerecordEntity.Id = YitIdHelper.NextId().ToString();
                _QmsBusiExemptionrulerecordEntity.MatnrCode = materialCode;
                _QmsBusiExemptionrulerecordEntity.OrderType = orderType;
                _QmsBusiExemptionrulerecordEntity.SupplierNo = supplierCode;
                _QmsBusiExemptionrulerecordEntity.RuleCode = ruleInfo.RuleCode;
                _QmsBusiExemptionrulerecordEntity.Stage = data.Stage;
                _QmsBusiExemptionrulerecordEntity.QualifiedInspNumber = 0;
                _QmsBusiExemptionrulerecordEntity.UnqualifiedInspNumber = 0;
                _QmsBusiExemptionrulerecordEntity.EnabledMark = 1;
                _QmsBusiExemptionrulerecordEntity.CreatorTime = DateTime.Now;
                _QmsBusiExemptionrulerecordEntity.CreatorUserId = isLogin ? userManager.UserId : "system";
                var isOk = await _repository.Context.Insertable(_QmsBusiExemptionrulerecordEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                if (isOk < 1)
                    throw Oops.Oh("保存跳检规则记录失败");

                recordId = _QmsBusiExemptionrulerecordEntity.Id;
            }
        }
        JObject jObject = new JObject();
        jObject.Add("id", recordId);
        jObject.Add("isExempt", data.IsExempt);
        return jObject;

    }

    /// <summary>
    /// 校验规则
    /// </summary>
    /// <param name="recordInfo"></param>
    /// <param name="stageInfo"></param>
    /// <returns></returns>
    private async Task<QmsBaseInspectionroleEntity> CheckRule(QmsBusiExemptionrulerecordEntity recordInfo, QmsBaseInspectionroleEntity stageInfo, bool isLogin)
    {
        string stage = recordInfo.Stage;
        var currentDate = DateTime.Now;
        // 计算间隔天数
        var d = (int)((currentDate - recordInfo.CreatorTime)?.TotalDays ?? 0);
        // 连续天数是否达成
        bool dayCheckResult = false;
        if (stageInfo.JudeCondition.Equals("=") && d == stageInfo.ContinuityDay)
        {
            dayCheckResult = true;
        }
        else if (stageInfo.JudeCondition.Equals(">") && d > stageInfo.ContinuityDay)
        {
            dayCheckResult = true;
        }
        else if (stageInfo.JudeCondition.Equals("<") && d < stageInfo.ContinuityDay)
        {
            dayCheckResult = true;
        }
        else if (stageInfo.JudeCondition.Equals(">=") && d >= stageInfo.ContinuityDay)
        {
            dayCheckResult = true;
        }
        else if (stageInfo.JudeCondition.Equals("<=") && d <= stageInfo.ContinuityDay)
        {
            dayCheckResult = true;
        }
        // 合格数量是否达成
        bool okQtyCheckResult = false;
        if (stageInfo.InspLot != 0 && recordInfo.QualifiedInspNumber >= stageInfo.InspLot)
        {
            okQtyCheckResult = true;
        }
        // 不合格数量是否达成
        bool ngQtyCheckResult = false;
        if (stageInfo.RejectNun != 0 && recordInfo.UnqualifiedInspNumber >= stageInfo.RejectNun)
        {
            ngQtyCheckResult = true;
        }

        if (stageInfo.KeyWord.Equals("and") && dayCheckResult && okQtyCheckResult)
        {
            stage = stageInfo.OkStageNo;
        }
        else if (stageInfo.KeyWord.Equals("or") && (dayCheckResult || okQtyCheckResult))
        {
            stage = stageInfo.OkStageNo;
        }

        if (ngQtyCheckResult)
        {
            stage = stageInfo.NgStageNo;
        }

        // 已经不是当前阶段了，则查询新阶段的信息
        if (!stage.Equals(recordInfo.Stage))
        {
            // 跳出免检阶段需要推送消息
            if (stageInfo.IsExempt == 1)
            {
                // 跳出免检阶段需要推送消息，待实现
            }

            stageInfo = await _repository.Context.Queryable<QmsBaseInspectionrolemainEntity, QmsBaseInspectionroleEntity>((a, b) => a.Id == b.MainId).Where((a, b) => a.Code == recordInfo.RuleCode && b.Stage == stage && a.DeleteMark == null && a.EnabledMark == 1 && b.DeleteMark == null && b.EnabledMark == 1).Select((a, b) => b).FirstAsync();
            if (stageInfo == null)
                throw Oops.Oh("根据跳检规则记录未查询到跳检配置，请确认");

            QmsBusiExemptionrulerecordEntity _QmsBusiExemptionrulerecordEntity = new QmsBusiExemptionrulerecordEntity();
            _QmsBusiExemptionrulerecordEntity.Id = YitIdHelper.NextId().ToString();
            _QmsBusiExemptionrulerecordEntity.MatnrCode = recordInfo.MatnrCode;
            _QmsBusiExemptionrulerecordEntity.OrderType = recordInfo.OrderType;
            _QmsBusiExemptionrulerecordEntity.SupplierNo = recordInfo.SupplierNo;
            _QmsBusiExemptionrulerecordEntity.RuleCode = recordInfo.RuleCode;
            _QmsBusiExemptionrulerecordEntity.Stage = stage;
            _QmsBusiExemptionrulerecordEntity.QualifiedInspNumber = 0;
            _QmsBusiExemptionrulerecordEntity.UnqualifiedInspNumber = 0;
            _QmsBusiExemptionrulerecordEntity.EnabledMark = 1;
            _QmsBusiExemptionrulerecordEntity.CreatorTime = DateTime.Now;
            _QmsBusiExemptionrulerecordEntity.CreatorUserId = isLogin ? userManager.UserId : "system";
            var isOk = await _repository.Context.Insertable(_QmsBusiExemptionrulerecordEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            if (isOk < 1)
                throw Oops.Oh("保存跳检规则记录失败");

            // 跳阶段后返回新阶段记录的id
            recordInfo.Id = _QmsBusiExemptionrulerecordEntity.Id;

            // 进入免检阶段需要推送消息
            if (stageInfo.IsExempt == 1)
            {
                // 进入免检阶段需要推送消息，待实现
            }
        }
        return stageInfo;
    }

    private void Creator(CLDEntityBase entity, bool isLogin)
    {
        if (isLogin)
        {
            entity.Creator();
            return;
        }

        entity.CreatorUserId = "System";
        entity.CreatorTime = DateTime.Now;
        entity.Id = YitIdHelper.NextId().ToString();
        entity.EnabledMark = (!entity.EnabledMark.HasValue) ? 1 : entity.EnabledMark;
    }

    private void LastModify(CLDEntityBase entity, bool isLogin)
    {
        if (isLogin)
        {
            entity.LastModify();
            return;
        }

        entity.LastModifyTime = DateTime.Now;
        entity.LastModifyUserId = "System";
    }

    private string CustomerParamToJson(object parametersObj, string customParameterTypeKeyID)
    {
        var parameterResult = string.Empty;
        if (parametersObj is not null and string parameters)
        {
            var dataPs = parameters.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (dataPs.Any())
            {
                var resPs = _repository.Context.Queryable<DictionaryDataEntity>()
                 .Where(w => w.EnabledMark == 1)
                 .Where(w => w.DeleteMark == null)
                 .Where(w => w.DictionaryTypeId == customParameterTypeKeyID)
                 .Where(w => dataPs.Contains(w.Id) || dataPs.Contains(w.EnCode))
                 .Select(w => new { key = w.EnCode, label = w.FullName })
                 .ToList();
                parameterResult = resPs.ToJsonString();
            }
        }

        return parameterResult;
    }

    /// <summary>
    /// 国标AQL
    /// </summary>
    /// <param name="samplePlan"></param>
    /// <param name="incomingQty"></param>
    /// <param name="receivedQty"></param>
    /// <param name="rejectionQty"></param>
    /// <returns></returns>
    private decimal GBAQL(QmsBaseCheckcardsampleEntity samplePlan, int incomingQty, out decimal receivedQty, out decimal rejectionQty)
    {
        var gbAQL = _repository.Context.Queryable<QmsBaseNationalstandardEntity>()
            .Where(w => w.EnabledMark == 1)
            .Where(w => w.DeleteMark == null)
            .Where(w => w.QualityLimit == samplePlan.GQualityLimit)
            .Where(w => w.InspectionLevel == samplePlan.GLevel)
            .Where(w => w.Stage == samplePlan.GStringency)
            .Where(w => w.LowerLimit <= incomingQty && w.UpperLimit >= incomingQty)
            .Select(w => w)
            .First() ?? throw Oops.Oh($"无可用的国标AQL抽样方案项目：国际质量限({samplePlan.GQualityLimit}) 国际严格度({samplePlan.GStringency}) 检验水平({samplePlan.GLevel}) 来料数量({incomingQty})！");

        // 如果是全检，样本数就=来料数
        var sampleQty = string.Equals("Y", gbAQL.AllInspection, StringComparison.OrdinalIgnoreCase)
            ? gbAQL.ReceivedQty ?? 0 : gbAQL.SampleQty ?? 0;
        receivedQty = gbAQL.ReceivedQty ?? 0;
        rejectionQty = 1;

        return sampleQty;
    }

    /// <summary>
    /// 固定比例
    /// </summary>
    /// <param name="samplePlan"></param>
    /// <param name="incomingQty"></param>
    /// <param name="receivedQty"></param>
    /// <param name="rejectionQty"></param>
    /// <returns></returns>
    private decimal FixRate(QmsBaseCheckcardsampleEntity samplePlan, int incomingQty, out decimal receivedQty, out decimal rejectionQty)
    {
        // 如果是全检，样本数就=来料数
        var sampleQty = incomingQty == 0 ? 0 : Math.Max(1, Math.Round(samplePlan.FixedRatio / 100 * incomingQty));
        receivedQty = sampleQty;
        rejectionQty = 1;

        return sampleQty;
    }

    /// <summary>
    /// 自定义AQL
    /// </summary>
    /// <param name="aqlName"></param>
    /// <param name="incomingQty"></param>
    /// <param name="receivedQty"></param>
    /// <param name="rejectionQty"></param>
    /// <returns></returns>
    private decimal CoustomerAQL(string aqlName, int incomingQty, out decimal receivedQty, out decimal rejectionQty)
    {
        (decimal sampleQty, receivedQty, rejectionQty) = CoustomerAQL(aqlName, incomingQty);
        return sampleQty;
    }

    /// <summary>
    /// 自定义AQL.
    /// </summary>
    private (decimal SampleQty, decimal ReceivedQty, decimal RejectionQty) CoustomerAQL(string aqlName, int incomingQty)
    {
        var coustomerSamplingPlan = _repository.Context.Queryable<QmsBaseSamplingplanEntity>()
            .LeftJoin<QmsBaseSamplingplandetailEntity>((w, b) => w.Id == b.MainId)
            .Where(w => w.EnabledMark == 1)
            .Where(w => w.DeleteMark == null)
            .Where(w => w.Name == aqlName || w.Id == aqlName)
            .Where((w, b) => b.LowerLimit <= incomingQty && b.UpperLimit >= incomingQty)
            .Select((w, b) => b)
            .First() ?? throw Oops.Oh($"无可用的自定义AQL抽样方案项目：抽样方案({aqlName}),来料数量{incomingQty}！");

        var sampleQty = coustomerSamplingPlan.SampleQty ?? 0;
        var receivedQty = coustomerSamplingPlan.ReceivedQty ?? 0;
        var rejectionQty = coustomerSamplingPlan.RejectionQty ?? 0;

        return (sampleQty, receivedQty, rejectionQty);
    }

    /// <summary>
    /// 推送检验消息
    /// </summary>
    /// <param name="inspectionLotCode">检验批单据号</param>
    /// <param name="inspector">检验员</param>
    /// <param name="isLogin">当前操作是否为用户操作，反之为系统任务调度操作</param>
    private void SendMessageEvent(string inspectionLotCode, UserEntity inspector, bool isLogin = true)
    {
        // 处理推送消息
        JArray jArray = new JArray
        {
            new JObject
            {
                { "name", "来料检验单" },
                { "code", inspectionLotCode },
                { "status", "待检验" },
                { "userName", isLogin ? inspector.RealName : "system" },
                { "date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }
            }
        };
        messageService.AddMessageEvent("Inspection", inspector.Id, jArray.ToJsonString(), null, isLogin);
    }

    /// <summary>
    /// 获取检验员看板数据.
    /// </summary>
    /// <returns></returns>
    [HttpGet("InspectorKanban")]
    public async Task<dynamic> InspectorKanban()
    {
        // 查询报检单已经分配的检验员
        var queryable1 = _repository.Context.Queryable<QmsBusiInspectionEntity>()
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && x.Status == 0 && x.DeleteMark == null && x.EnabledMark == 1)
            .GroupBy(a => new { a.EmployeeCode })
            .Select(a => new QmsBusiInspectionListOutput
            {
                employeeCode = a.EmployeeCode
            });
        var queryable2 = _repository.Context.Queryable<QmsBusiInspectionlotEntity>()
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && (x.Status == 0 || x.Status == 1) && x.DeleteMark == null && x.EnabledMark == 1)
            .GroupBy(a => new { a.EmployeeCode })
            .Select(a => new QmsBusiInspectionListOutput
            {
                employeeCode = a.EmployeeCode
            });

        var inspectorList = await _repository.Context.Union(queryable1, queryable2).OrderBy(x => x.employeeCode, OrderByType.Asc).ToListAsync();

        JArray jArray = new JArray();
        int total = 0;
        foreach (var item in inspectorList)
        {
            JArray jArray1 = new JArray();
            var inspectionList = await _repository.Context.Queryable<QmsBusiInspectionEntity, QmsBaseMaterialEntity, QmsBaseSupplierEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null, JoinType.Left, a.Supplier == c.Code))
            .Where(a => a.EmployeeCode == item.employeeCode && a.Status == 0 && a.DeleteMark == null && a.EnabledMark == 1)
            .OrderBy(a => a.Date, OrderByType.Asc)
            .Select((a, b, c) => new QmsBusiInspectionListOutput
            {
                id = a.Id,
                inspectionCode = a.Code,
                materialCode = a.MaterialCode,
                material = b.Name,
                incomingQty = a.IncomingQty,
                date = a.Date,
                supplier = c.Name,
                supplierCode = a.Supplier,
                batchNumber = a.BatchNumber,
                overdue = a.Overdue
            }).ToListAsync();

            foreach (var inspection in inspectionList)
            {
                JObject jObject1 = new JObject();
                jObject1.Add("type", 1);
                jObject1.Add("id", inspection.id);
                jObject1.Add("code", inspection.inspectionCode);
                jObject1.Add("materialCode", inspection.materialCode);
                jObject1.Add("materialDes", inspection.material ?? "");
                jObject1.Add("incomingQty", inspection.incomingQty);
                jObject1.Add("date", inspection.date);
                jObject1.Add("supplierCode", inspection.supplierCode);
                jObject1.Add("supplierDes", inspection.supplier ?? "");
                jObject1.Add("batchNumber", inspection.batchNumber);
                jObject1.Add("overdue", inspection.overdue);
                jArray1.Add(jObject1);
            }

            var inspectionlotList = await _repository.Context.Queryable<QmsBusiInspectionlotEntity, QmsBaseMaterialEntity, QmsBaseSupplierEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null, JoinType.Left, a.Supplier == c.Code))
            .Where(a => a.EmployeeCode == item.employeeCode && (a.Status == 0 || a.Status == 1) && a.DeleteMark == null && a.EnabledMark == 1)
            .OrderBy(a => a.CreatorTime, OrderByType.Asc)
            .Select((a, b, c) => new QmsBusiInspectionlotListOutput
            {
                id = a.Id,
                code = a.Code,
                materialCode = a.MaterialCode,
                materialDes = b.Name,
                incomingQty = a.IncomingQty,
                date = a.Date,
                supplier = a.Supplier,
                supplierDes = c.Name,
                batchNumber = a.BatchNumber,
                overdue = a.Overdue
            }).ToListAsync();

            foreach (var inspectionlot in inspectionlotList)
            {
                JObject jObject1 = new JObject();
                jObject1.Add("type", 2);
                jObject1.Add("id", inspectionlot.id);
                jObject1.Add("code", inspectionlot.code);
                jObject1.Add("materialCode", inspectionlot.materialCode);
                jObject1.Add("materialDes", inspectionlot.materialDes ?? "");
                jObject1.Add("incomingQty", inspectionlot.incomingQty);
                jObject1.Add("date", inspectionlot.date);
                jObject1.Add("supplierCode", inspectionlot.supplier);
                jObject1.Add("supplierDes", inspectionlot.supplierDes ?? "");
                jObject1.Add("batchNumber", inspectionlot.batchNumber);
                jObject1.Add("overdue", inspectionlot.overdue);
                jArray1.Add(jObject1);
            }

            var count = inspectionList.Count + inspectionlotList.Count;
            total += count;

            var userInfo = await _repository.Context.Queryable<UserEntity>().Where(x => x.Account == item.employeeCode && x.DeleteMark == null).FirstAsync();
            JObject jObject = new JObject();
            jObject.Add("employeeCode", item.employeeCode);
            jObject.Add("employeeName", userInfo?.RealName);
            jObject.Add("headIcon", userInfo?.HeadIcon);
            jObject.Add("count", count);
            jObject.Add("list", jArray1);
            jArray.Add(jObject);
        }
        // 未分配的
        var waitList = await _repository.Context.Queryable<QmsBusiInspectionEntity, QmsBaseMaterialEntity, QmsBaseSupplierEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null, JoinType.Left, a.Supplier == c.Code))
            .Where((a, b, c) => string.IsNullOrEmpty(a.EmployeeCode) && a.DeleteMark == null && a.EnabledMark == 1).OrderBy(a => a.Date, OrderByType.Asc).Select((a, b, c) => new
            {
                id = a.Id,
                code = a.Code,
                materialCode = a.MaterialCode,
                materialDes = SqlFunc.IsNull(b.Name, ""),
                incomingQty = a.IncomingQty,
                date = a.Date,
                supplierCode = a.Supplier,
                supplierDes = SqlFunc.IsNull(c.Name, ""),
                batchNumber = a.BatchNumber,
                overdue = a.Overdue

            }).ToListAsync();

        // 已完成检验
        var finishList = await _repository.Context.Queryable<QmsBusiInspectionlotEntity>()
            .GroupBy(x => new { x.EmployeeCode, x.EmployeeName })
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && x.Status == 3 && x.DeleteMark == null && x.EnabledMark == 1)
            .OrderBy(x => x.EmployeeCode, OrderByType.Asc)
            .Select(x => new
            {
                employeeCode = x.EmployeeCode,
                employeeName = SqlFunc.Subqueryable<UserEntity>().Where(a => a.Account == x.EmployeeCode && a.DeleteMark == null).Select(a => a.RealName),
                headIcon = SqlFunc.Subqueryable<UserEntity>().Where(a => a.Account == x.EmployeeCode && a.DeleteMark == null).Select(a => a.HeadIcon),
                count = SqlFunc.AggregateCount(x.EmployeeCode)
            }).ToListAsync();

        return new { list = jArray, total = total, wait = waitList, finish = finishList };
    }

    /// <summary>
    /// 分配检验员.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("AssignInspector")]
    public async Task AssignInspector([FromBody] JObject _data)
    {
        string id = _data["id"].ToString();
        string employeeCode = _data["employeeCode"].ToString();
        string employeeName = _data["employeeName"].ToString();
        string type = _data["type"].ToString();

        // 如果是检验批则更新检验批
        if (type.Equals("2"))
        {
            var isOk = await _repository.Context.Updateable<QmsBusiInspectionlotEntity>().SetColumns(it => new QmsBusiInspectionlotEntity()
            {
                EmployeeCode = employeeCode,
                EmployeeName = employeeName,
                LastModifyTime = DateTime.Now,
                LastModifyUserId = userManager.UserId
            }).Where(x => x.Id == id && (x.Status == 0 || x.Status == 1) && x.DeleteMark == null && x.EnabledMark == 1).ExecuteCommandHasChangeAsync();
            if (!isOk)
                throw Oops.Oh(ErrorCode.COM1001);
        }
        else
        {
            // 否则更新报检单
            var isOk = await _repository.Context.Updateable<QmsBusiInspectionEntity>().SetColumns(it => new QmsBusiInspectionEntity()
            {
                EmployeeCode = employeeCode,
                EmployeeName = employeeName,
                LastModifyTime = DateTime.Now,
                LastModifyUserId = userManager.UserId
            }).Where(x => x.Id == id).ExecuteCommandHasChangeAsync();
            if (!isOk)
                throw Oops.Oh(ErrorCode.COM1001);
        }
    }


}